/*
 * File Name: DesEncrypter.java
 * Release: 1.0 
 * Copyrights (c) 2005 lingtong.
 * 
 * �޸���   : cbshen
 * �޸�ʱ�� : 2006-2-14
 * �޸ļ�¼ :
 *   1.��ӱ��� 2006-2-14 cbshen
 */
package com.wsj.common.wsjSecurity;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>
 * DES����
 * </p>
 * 
 * @author cbshen
 * @version 1.0
 * @since 2006-2-14
 */
public class DesEncrypter {
	/**
	 * Logger for this class
	 */
	private static final Log logger = LogFactory.getLog(DesEncrypter.class);

	/** 
	 * 加密对象
	 * 
	������ */
	private Cipher ecipher;

	/** �����
	 * 解密对象
	 * 
	� */
	private Cipher dcipher;

	/**
	 * 安全算法KEY
	 */
	private final static String keyFileName = "desEncrypt.key";

	/**
	 * 初始化解密对象参数��
	 * 
	 * @param key
	 *            ���ķ�ʽ
	 */
	private DesEncrypter(SecretKey key) {
		try {
			ecipher = Cipher.getInstance("DES");
			dcipher = Cipher.getInstance("DES");
			ecipher.init(Cipher.ENCRYPT_MODE, key);
			dcipher.init(Cipher.DECRYPT_MODE, key);
		} catch (javax.crypto.NoSuchPaddingException e) {
			logger.error(e.getMessage());
		} catch (java.security.NoSuchAlgorithmException e) {
			logger.error(e.getMessage());
		} catch (java.security.InvalidKeyException e) {
			logger.error(e.getMessage());
		}
	}

	/**
	 * 二行制转字符串
	 * @param in
	 * @return
	 */
	public static byte[] addParity(byte[] in) {
		byte[] result = new byte[8];

		// Keeps track of the bit position in the result
		int resultIx = 1;

		// Used to keep track of the number of 1 bits in each 7-bit chunk
		int bitCount = 0;

		// Process each of the 56 bits
		for (int i = 0; i < 56; i++) {
			// Get the bit at bit position i
			boolean bit = (in[6 - i / 8] & (1 << (i % 8))) > 0;

			// If set, set the corresponding bit in the result
			if (bit) {
				result[7 - resultIx / 8] |= (1 << (resultIx % 8)) & 0xFF;
				bitCount++;
			}

			// Set the parity bit after every 7 bits
			if ((i + 1) % 7 == 0) {
				if (bitCount % 2 == 0) {
					// Set low-order bit (parity bit) if bit count is even
					result[7 - resultIx / 8] |= 1;
				}
				resultIx++;
				bitCount = 0;
			}
			resultIx++;
		}
		return result;
	}

	/**
	 * 执行密码加密
	 * @param p_str 原始密码
	 * @return 加密后的字符串
	 */
	private String encryptStr(String str) throws Exception {
		// Encode the string into bytes using utf-8
		byte[] utf8 = str.getBytes("UTF8");
		// Encrypt
		byte[] enc = ecipher.doFinal(utf8);
		// Encode bytes to base64 to get a string
		return new sun.misc.BASE64Encoder().encode(enc);
	}

	/**
	 * 执行密码解密
	 * @param p_str 加密后的密码
	 * @return 加密后的字符串
	 */
	private String decryptStr(String str) throws Exception {
		// Decode base64 to get bytes
		byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
		// Decrypt
		byte[] utf8 = dcipher.doFinal(dec);
		// Decode using utf-8
		return new String(utf8, "UTF8");
	}

	/**
	 * 密码加密
	 * @param p_str 原始密码
	 * @return 加密后的字符串
	 */
	public static String encrypt(String p_str) throws Exception {
		if (p_str == null) {
			return "";
		}
		// ObjectInputStream input = null;
		InputStream input = null;

		input = DesEncrypter.class.getResourceAsStream(keyFileName);
		List<Byte> l_bList = new ArrayList<Byte>();
		int l_re;
		while ((l_re = input.read()) != -1) {
			l_bList.add(new Byte((byte) l_re));
		}
		byte[] keyByte = new byte[l_bList.size()];
		for (int i = 0; i < keyByte.length; i++) {
			keyByte[i] = ((Byte) l_bList.get(i)).byteValue();
		}
		SecretKey key = new javax.crypto.spec.SecretKeySpec(keyByte, "DES");

		DesEncrypter en = new DesEncrypter(key);

		if (input != null) {
			input.close();
		}

		return en.encryptStr(p_str);
	}

	/**
	 * 密码解密
	 * @param p_str 加密后的密码
	 * @return 加密后的字符串
	 */
	public static String decrypt(String p_str) throws Exception {
		if (p_str == null) {
			return "";
		}

		InputStream input = null;

		input = DesEncrypter.class.getResourceAsStream(keyFileName);
		List<Byte> l_bList = new ArrayList<Byte>();
		int l_re;
		while ((l_re = input.read()) != -1) {
			l_bList.add(new Byte((byte) l_re));
		}
		byte[] keyByte = new byte[l_bList.size()];
		for (int i = 0; i < keyByte.length; i++) {
			keyByte[i] = ((Byte) l_bList.get(i)).byteValue();
		}
		SecretKey key = new javax.crypto.spec.SecretKeySpec(keyByte, "DES");
		DesEncrypter en = new DesEncrypter(key);

		if (input != null) {

			input.close();

		}
		
		return en.decryptStr(p_str);

	}
	
	/****
	 * main 函数
	 * @param arg
	 */
	public static void main(String[] arg){
		String jiami="";
		String jiemi="";
//		try {
//			jiami = DesEncrypter.encrypt("fengbin");
//			System.out.println("fengbin:"+jiami);
//			jiemi = DesEncrypter.decrypt("pZ8G1EdueOI=");
//			System.out.println("pZ8G1EdueOI=:"+jiemi);
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		
		
		
		
	}
}
